﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Globalization;
using ProgNetComponents.Collections;
using ProgNetComponents.Classes;

namespace ProgNetComponents.Design.Editors.Forms
{
    /// <summary>
    /// ObjectEditorForm
    /// </summary>
    public partial class ObjectEditorForm : Form
    {
        /// <summary>
        /// objEditValue
        /// </summary>
        private object objEditValue;

        /// <summary>
        /// oldEditor
        /// </summary>
        private Control oldEditor;
        /// <summary>
        /// lockUpdate
        /// </summary>
        private bool lockUpdate;
        /// <summary>
        /// Gets the editor.
        /// </summary>
        /// <value>
        /// The editor.
        /// </value>
        private Control Editor
        {
            get
            {
                switch (this.comboType.SelectedIndex)
                {
                    case 0:
                        return null;
                    case 5:
                        return this.cmbEditor;
                    case 6:
                        return this.dtEditor;
                    case 4:
                        txtEditor.Multiline = true;
                        txtEditor.Height = 180;
                        this.Height = 290;
                        return this.txtEditor;
                    default:
                        txtEditor.Multiline = false;
                        return this.txtEditor;
                }
            }
        }
        /// <summary>
        /// coll
        /// </summary>
        NamedObjectCollection coll = new NamedObjectCollection();

        /// <summary>
        /// Gets the edit value.
        /// </summary>
        /// <value>
        /// The edit value.
        /// </value>
        public object EditValue
        {
            get
            {
                Control editor = Editor;
                if (editor != null)
                {
                    NamedObject o = comboType.SelectedItem as NamedObject;
                    if (o != null && o.Value !=null)
                    {
                        if (editor == txtEditor)
                        {
                            string str = txtEditor.Text;
                            if ((Type)(o.Value) == typeof(decimal))
                                return str.AsDecimal();
                            if ((Type)(o.Value) == typeof(int))
                                return str.AsInt();
                            return str;
                        }
                        else if (editor == cmbEditor)
                        {
                            if (cmbEditor.SelectedIndex == 0)
                                return true;
                            return false;
                        }
                        else
                        {
                            return dtEditor.Value;
                        }
                    }
                }
                return null;
            }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="ObjectEditorForm"/> class.
        /// </summary>
        /// <param name="editValue">The edit value.</param>
        public ObjectEditorForm(object editValue)
        {
            InitializeComponent();
            SetTypes();
            this.comboType.DataSource = coll;
           
            objEditValue = editValue;
            int idx = -1;
            if (editValue == null)
                idx = 0;
            else
            {
                string type = editValue.GetType().Name;
                if (editValue is string && editValue.AsString().Contains("\n"))
                    type = "String (Multiline)";
                idx = coll.IndexOf(type);
            }

            this.comboType.SelectedIndex = idx;
            this.btnOK.Enabled = false;
        }
        /// <summary>
        /// Sets the types.
        /// </summary>
        private void SetTypes()
        {
            coll.Add(new NamedObject("<NULL>", null));
            AddType(typeof(int));
            AddType(typeof(decimal));
            AddType(typeof(string));
            coll.Add(new NamedObject("String (Multiline)", typeof(string)));
            AddType(typeof(bool));
            AddType(typeof(DateTime));
        }

        /// <summary>
        /// Adds the type.
        /// </summary>
        /// <param name="t">The t.</param>
        private void AddType(Type t)
        {
            coll.Add(new NamedObject(t.Name, t));
        }

        /// <summary>
        /// Handles the SelectedIndexChanged event of the comboType control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        private void comboType_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.lockUpdate = true;
            Control editor = this.Editor;
            if (editor != null)
            {
                if (this.oldEditor != null && this.oldEditor == this.txtEditor)
                    this.objEditValue = this.oldEditor.Text;

                this.txtEditor.Visible = editor == txtEditor;
                this.cmbEditor.Visible = editor == cmbEditor;
                this.dtEditor.Visible = editor == dtEditor;

                if (editor == cmbEditor)
                {
                    this.cmbEditor.SelectedIndex = this.objEditValue.AsBool() ? 0 : 1;
                }
                else if (editor.Equals((object)this.dtEditor))
                {
                    try
                    {
                        this.dtEditor.Value = this.objEditValue.AsDateTime(DateTime.Now);
                    }
                    catch
                    {
                        this.dtEditor.Value = DateTime.Now;
                    }
                }
                else
                    this.txtEditor.Text = this.objEditValue.AsString();
                this.oldEditor = editor;
            }
            else
                this.txtEditor.Visible = this.cmbEditor.Visible = this.dtEditor.Visible = false;
            this.btnOK.Enabled = true;
            this.lockUpdate = false;
        }

        /// <summary>
        /// Handles the TextChanged event of the editor control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        private void editor_TextChanged(object sender, EventArgs e)
        {
            if (!this.lockUpdate)
                this.btnOK.Enabled = true;
        }

    }
}
